//
//  ViewController.m
//  RuntimeDemo
//
//  Created by shanezhang on 14-8-28.
//  Copyright (c) 2014年 TimeRadio. All rights reserved.
//

#import "ViewController.h"
#import <objc/runtime.h>
#import "CustomClass.h"
#import "TestClass.h"
#import "CustomClassOther.h"

/**
 * 一个参数
 *
 */

int cfunction(id self, SEL _cmd, NSString *str)
{
    NSLog(@"%@", str);
    
    return 10;//随便返回个值
}


/**
 * 两个参数
 *
 */

int cfunctionA(id self, SEL _cmd, NSString *str, NSString *str1)
{
    NSLog(@"%@ - %@", str, str1);
    
    return 20;//随便返回个值
}



@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
//    [self copyObj];
//    [self setClassTest];
//    [self getClassTest];
//    [self getClassName];
//    [self oneParam];
    [self twoParam];
}


/**
 *  对象拷贝的方法
 */
- (void) copyObj
{
    CustomClass *obj = [CustomClass new];
    NSLog(@"%p", &obj);
    
    id objTest = object_copy(obj,sizeof(obj));
    
    NSLog(@"%p", &objTest);
    
    [objTest fun1];
    
    
    /**
     *  object_copy 函数实现了对象的拷贝。
     */
    
//    2014-08-28 16:25:28.383 RuntimeDemo[2470:60b] 0x27d80804
//    2014-08-28 16:25:28.385 RuntimeDemo[2470:60b] 0x27d80800
//    2014-08-28 16:25:28.386 RuntimeDemo[2470:60b] fun1
}

/**
 *  对象的释放,程序crash
 */
- (void) objectDispose
{
    CustomClass *obj = [CustomClass new];
    object_dispose(obj);
    
    [obj release];
    [obj fun1];
}

/**
 *  Class object_setClass(id obj, Class cls)  ／  Class object_getClass(id obj)
 */
- (void) setClassTest
{
    
    CustomClass *obj = [CustomClass new];
    [obj fun1];
    

    Class aClass = object_setClass(obj,[CustomClassOther class]);
    //obj 对象的类被更改了    swap the isa to an isa
    NSLog(@"aClass:%@",NSStringFromClass(aClass));
    NSLog(@"obj class:%@",NSStringFromClass([obj class]));
    [obj func2];
    // 动态得调用其他类的方法
//    2014-08-28 16:41:12.549 RuntimeDemo[2500:60b] fun1
//    2014-08-28 16:41:12.551 RuntimeDemo[2500:60b] aClass:CustomClass
//    2014-08-28 16:41:12.552 RuntimeDemo[2500:60b] obj class:CustomClassOther
//    2014-08-28 16:41:12.554 RuntimeDemo[2500:60b] func2
}

- (void) getClassTest
{
    CustomClass *obj = [CustomClass new];
    Class aLogClass =object_getClass(obj);
    NSLog(@"%@",NSStringFromClass(aLogClass));
    
//    2014-08-28 16:40:21.221 RuntimeDemo[2494:60b] CustomClass

}

/**
 *  获取对象的类名字  constchar *object_getClassName(id obj)
 */
- (void)getClassName
{
    CustomClass *obj = [CustomClass new];
    NSString *className = [NSString stringWithCString:object_getClassName(obj) encoding:NSUTF8StringEncoding];
    
    NSLog(@"className:%@", className);
    
//    2014-08-28 16:47:30.988 RuntimeDemo[2507:60b] className:CustomClass
}


/**
 *  给类动态添加一个方法的演示代码
    BOOL class_addMethod(Class cls,SEL name,IMP imp,  const char *types) 
 */
- (void)oneParam 
{
    
    TestClass *instance = [[TestClass alloc]init];
    //    方法添加
    class_addMethod([TestClass class],@selector(ocMethod:), (IMP)cfunction,"i@:@");
    
    if ([instance respondsToSelector:@selector(ocMethod:)]) 
    {
        NSLog(@"Yes, instance respondsToSelector:@selector(ocMethod:)");
    } 
    else
    {
        NSLog(@"Sorry");
    }
    
    int a = (int)[instance ocMethod:@"我是一个OC的method，C函数实现"];
    NSLog(@"a:%d", a);
}

- (int)ocMethod:(NSString *)string
{
    NSLog(@"onOCMethod: %@",string);
    return 20;  
}


- (void) twoParam 
{
    
    TestClass *instance = [[TestClass alloc]init];
    
    class_addMethod([TestClass class],@selector(ocMethodA::), (IMP)cfunctionA,"i@:@@");
    
    if ([instance respondsToSelector:@selector(ocMethodA::)])
    {
        NSLog(@"Yes, instance respondsToSelector:@selector(ocMethodA::)");
    } 
    else
    {
        NSLog(@"Sorry");
    }
    
    int a = (int)[instance ocMethodA:@"我是一个OC的method，C函数实现" :@"-----我是第二个参数"];
    NSLog(@"a:%d", a);
    
//    2014-08-28 17:06:26.277 RuntimeDemo[2544:60b] Yes, instance respondsToSelector:@selector(ocMethodA::)
//    2014-08-28 17:06:26.279 RuntimeDemo[2544:60b] 我是一个OC的method，C函数实现 - -----我是第二个参数
//    2014-08-28 17:06:26.281 RuntimeDemo[2544:60b] a:20
    
    
    
    
//    向一个类动态添加方法
//    
//    BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
//    参数说明：
//    cls：被添加方法的类
//    name：可以理解为方法名
//    imp：实现这个方法的函数
//    types：一个定义该函数返回值类型和参数类型的字符串
//    
//    
//    
//    class_addMethod([TestClass class], @selector(ocMethod:), (IMP)testFunc, "i@:@");
//    
//    其中types参数为"i@:@“，按顺序分别表示：
//    i：返回值类型int，若是v则表示void
//    @：参数id(self)
//    :：SEL(_cmd)
//    @：id(str)
}

- (int)ocMethodA:(NSString *)string1 :(NSString *)para2
{
    NSLog(@"onocMethodA: %@ - %@",string1,para2);
    
    return 0;
}
@end
